package com.plexpt.chatgptonlinejava.app;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.plexpt.chatgpt.entity.chat.ChatCompletionResponse;
import com.plexpt.chatgpt.entity.chat.Message;

import org.jetbrains.annotations.NotNull;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;

import java.util.Objects;
import java.util.function.Consumer;

import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.Resource;

/**
 * 描述：OpenAIEventSourceListener
 *
 * @author https:www.unfbx.com
 * @date 2023-02-22
 */
@Slf4j
public class GPTEventSourceListener extends EventSourceListener {

    private final RBlockingDeque<String> deque;

    public GPTEventSourceListener(String taskId) {
        RedissonClient client = SpringUtil.getBean(RedissonClient.class);
        this.deque = client.getBlockingDeque(taskId);
    }

    String last = "";
    @Setter
    Consumer<String> onComplate = s -> {

    };

    /**
     * {@inheritDoc}
     */
    @Override
    public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {

    }

    /**
     * {@inheritDoc}
     */
    @SneakyThrows
    @Override
    public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
        if (data.equals("[DONE]")) {
            // todo 存redis
            deque.addLast("[DONE]");
            return;
        }

        ChatCompletionResponse completionResponse = JSON.parseObject(data,
                ChatCompletionResponse.class); // 读取Json
        Message delta = completionResponse.getChoices().get(0).getDelta();
        String text = delta.getContent();
        if (text != null) {
            last += text;
            // todo 存redis
            deque.addLast(text);
        }
    }


    @Override
    public void onClosed(@NotNull EventSource eventSource) {
        // todo 存redis
        deque.addLast("[DONE]");
    }


    @SneakyThrows
    @Override
    public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
        if (Objects.isNull(response)) {
            return;
        }
        ResponseBody body = response.body();
        if (Objects.nonNull(body)) {
            log.error("OpenAI  sse连接异常data：{}，异常：", body.string(), t);
        } else {
            log.error("OpenAI  sse连接异常data：{}，异常：", response, t);
        }
        eventSource.cancel();
        // todo 存redis
        log.info("SSE连接异常");
        deque.addLast("[DONE]");
    }
}
